package com.shujia.spark.mllib

import org.apache.spark.ml.linalg
import org.apache.spark.ml.linalg.Vectors
import org.apache.spark.sql.{DataFrame, SparkSession}

object Demo01Vector {
  def main(args: Array[String]): Unit = {
    /**
     * Spark MLLib提供了两套API：
     * mllib：基于RDD
     * ml：基于DF
     */

    // 稠密向量：通过Array[Double]数组或者一组Double类型的值构建
    // 每一个值可以看成一个特征
    val denseVec: linalg.Vector = Vectors.dense(1.0, 2.0, 0.0, 3.0, 4.0, 5.0)
    println(denseVec)

    // 稀疏向量：需要size+有值的位置的下标+对应有值的位置的值 进行构建
    println(denseVec.toSparse)

    /**
     * 如何选择？
     * 大部分位置都有值，即特征基本上都有值，选择稠密向量
     * 大部分位置都是0，即有很多特征值缺失，选择稀疏向量
     */

    val sparseVec: linalg.Vector = Vectors.sparse(100, Array(0, 99), Array(1.0, 100.0))
    println(sparseVec)
    println(sparseVec.toDense)

    // 1:5.3 2:3.5 3:2.5 4:106.4 5:67.5 6:69.1 7:83
    val personDenseVec: linalg.Vector = Vectors.dense(5.3, 3.5, 2.5, 106.4, 67.5, 69.1, 83)
    println(personDenseVec)
    println(personDenseVec.toSparse)

    // 加载libsvm格式数据
    val spark: SparkSession = SparkSession
      .builder()
      .appName(this.getClass.getSimpleName.replace("$", ""))
      .master("local")
      .config("spark.sql.shuffle.partitions", "2")
      .getOrCreate()

    val personDF: DataFrame = spark
      .read
      .format("libsvm")
      .load("spark/data/mllib/data/personIndex.txt")

    personDF.printSchema()
    personDF.show(truncate = false)
  }

}
